namespace ScrumSprintMonitor.Implementation
{
    #region #using Directives

    using System;

    using Infrastructure;

    using Microsoft.Practices.Unity;

    #endregion

    public class ConnectionProvider : IConnectionProvider,
                                      IDisposable
    {
        private readonly IUnityContainer container;
        private IConnection connection;
        private Uri serverUri;

        public ConnectionProvider(IUnityContainer container)
        {
            this.container = container;
        }

        #region Implementation of IConnectionProvider

        public IConnection ProvideConnectionTo(Uri requestedServerUri, string userName, string password, bool reuseExisting)
        {
            if (reuseExisting && requestedServerUri.Equals(this.serverUri))
            {
                return this.connection;
            }

            if (userName == null)
            {
                userName = string.Empty;
            }
            if (password == null)
            {
                password = string.Empty;
            }

            var parameters = new[]
                                 {
                                     new ParameterOverride("serverUri", requestedServerUri), new ParameterOverride("userName", userName),
                                     new ParameterOverride("password", password)
                                 };
            var requestedConnection = this.container.Resolve<IConnection>(parameters);

            DisposeConnections();

            this.serverUri = requestedServerUri;
            this.connection = requestedConnection;

            return this.connection;
        }

        private void DisposeConnections()
        {
            IDisposable disposable = this.connection;
            if (disposable != null)
            {
                disposable.Dispose();
            }

            this.serverUri = null;
            this.connection = null;
        }

        #endregion

        #region Implementation of IDisposable

        public void Dispose()
        {
            DisposeConnections();
        }

        #endregion
    }
}
